/*
 * @(#)PatientRegistryService.java
 * Date 2013-08-23
 * Version 1.0
 * Author Jim Horner
 * Copyright (c)2012
 */


package us.hornerscorners.lamppost.pix.service.es;

import java.util.List;

import javax.annotation.PostConstruct;

import javax.enterprise.context.ApplicationScoped;

import javax.enterprise.inject.Alternative;

import javax.inject.Inject;

import org.elasticsearch.action.bulk.BulkResponse;

import org.hl7.v3.MCCIIN000002UV01;
import org.hl7.v3.PRPAIN201301UV02;
import org.hl7.v3.PRPAIN201301UV02MFMIMT700701UV01ControlActProcess;
import org.hl7.v3.PRPAIN201301UV02MFMIMT700701UV01RegistrationEvent;
import org.hl7.v3.PRPAIN201301UV02MFMIMT700701UV01Subject1;
import org.hl7.v3.PRPAIN201301UV02MFMIMT700701UV01Subject2;
import org.hl7.v3.PRPAMT201301UV02Patient;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import us.hornerscorners.lamppost.config.BasicServiceConfig;

import us.hornerscorners.lamppost.exception.ServiceActionException;

import us.hornerscorners.lamppost.hl7v3common.constant.AckResponse;

import us.hornerscorners.lamppost.ihecommon.config.IHEConfig;
import us.hornerscorners.lamppost.ihecommon.config.IHEServiceType;

import us.hornerscorners.lamppost.ihecommon.service.ElasticSearchSource;

import us.hornerscorners.lamppost.model.patient.Patient;

import us.hornerscorners.lamppost.pix.model.PatientRegistryResponse;

import us.hornerscorners.lamppost.pix.service.IPatientRegistryService;

import us.hornerscorners.lamppost.pix.transformer.PatientTransformer;

import us.hornerscorners.lamppost.pix.transformer.hl7.MCCIIN000002UV01Transformer;


/**
 *
 * @author jim
 *
 */
@ApplicationScoped
@Alternative
public class PatientRegistryService implements IPatientRegistryService {

    /** Field description */
    @Inject
    private IHEConfig config;

    /** Field description */
    private final Logger logger = LoggerFactory.getLogger(getClass());

    /** Field description */
    @Inject
    private PatientTransformer patientTransformer;

    /** Field description */
    @Inject
    private MCCIIN000002UV01Transformer responseTransformer;

    /** Field description */
    private BasicServiceConfig serviceConfig;

    /** Field description */
    @Inject
    private ElasticSearchSource source;

    /**
     * Constructs ...
     *
     */
    public PatientRegistryService() {
        super();
    }

    /**
     * Method description
     *
     *
     * @param prpa301
     *
     * @return
     */
    private PRPAMT201301UV02Patient parsePatient(PRPAIN201301UV02 prpa301) {

        PRPAMT201301UV02Patient result = null;

        PRPAIN201301UV02MFMIMT700701UV01ControlActProcess controlAct =
            prpa301.getControlActProcess();

        if (controlAct != null) {

            List<PRPAIN201301UV02MFMIMT700701UV01Subject1> subjects =
                controlAct.getSubject();

            if (subjects.isEmpty() == false) {

                PRPAIN201301UV02MFMIMT700701UV01RegistrationEvent regEvent =
                    subjects.get(0).getRegistrationEvent();

                PRPAIN201301UV02MFMIMT700701UV01Subject2 subject1 =
                    regEvent.getSubject1();

                if (subject1 != null) {

                    result = subject1.getPatient();
                }
            }
        }

        return result;
    }

    /**
     * Method description
     *
     */
    @PostConstruct
    public void postConstruct() {

        this.serviceConfig =
            (BasicServiceConfig) this.config.findServiceConfig(IHEServiceType.PIX);
    }

    /**
     * Method description
     *
     *
     * @param prpa301
     *
     * @return
     *
     */
    @Override
    public MCCIIN000002UV01 registerPatient(PRPAIN201301UV02 prpa301) {

        MCCIIN000002UV01 result = null;
        PRPAMT201301UV02Patient prpaPatient = parsePatient(prpa301);

        if (prpaPatient != null) {

            BulkResponse writeResponse = null;

            try {

                Patient patient = this.patientTransformer.transform(prpaPatient);

                writeResponse = this.source.writePersistable(patient);

                if (writeResponse.hasFailures()) {

                    this.source.rollbackTransaction(writeResponse);

                } else {

                    PatientRegistryResponse response =
                        new PatientRegistryResponse(this.serviceConfig, prpa301,
                                                    AckResponse.CommitAck);

                    result = this.responseTransformer.transform(response);
                }

            } catch (ServiceActionException e) {

                // TODO capture exception
                // TODO set result
            }
        }

        return result;
    }
}
